iOS – Fake GPS position: how to use and prevent

Very often a lots of iOS applications use your gps position to retrieve data or to lock / unlock contents positions based.

With Android you can use lots of apps called Fake GPS or similar that allow you to change your real gps position with a mocked one.

On Android development side this can be blocked checking via code the:

android.permission.ACCESS_MOCK_LOCATION

On iOS instead there is no way to avoid this.

Use mocked position on iOS

In order to change your real device GPS position using a fake one you need:

Mac book

Xcode

A valid development certificate

Let’s fake! – basic

Create a new empty project, build and run it on physical device.

From XCode debugger, choose the GPS position from the list:

You’re now flight to Johannesburg in South Africa!

DON’T CLOSE YOUR APP, put only in background and open the Maps app: you see the new position instead of your real one:

Instead of using Maps you can open Pokemon Go (as already explained here) and catch Pokemon around the world directly from your desk!

Cool but, this location is static… I want to move around, I want to go to visit Lecce, how can I do it?

Let’s fake! – advanced

Create your new custom GPX file: https://it.wikipedia.org/wiki/GPS_eXchange_Format

From XCode -> File -> Add new and select GPX file.

The GPX file can contains static or dynamic GPS informations you want to use in your XCode. Adding this new file you see it directly in the combo-box described above. And of course you can select it to use in your device!

For instance you can draw your track using this site (that I like a lot) https://www.alltrails.com/explore/map/alberto-bg:

And export as GPX file and next add to your XCode project.

GPX file can also be static, this an example:

<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode">
<wpt lat="45.698517684337375" lon="9.677476069724928">
<name>Bergamo</name>
2014-09-24T14:55:37Z
</wpt>
</gpx>

Avoid use of mocked GPX in your application

I’ve prepared for this post, a simple SDK, available for edits on Github called GPSSecurity that can helps you a little bit to check the validity of the user position.

You can add in your project using Cocoapod:

pod 'GPSSecurity', git: 'https://github.com/elpsk/GPSSecurity.git'

and use in your project:

import GPSSecurity

[..]
{
GPSValidator().positionValid(currentPosition: yourDeviceLocation) { validLocation in
print("Valid position?: \(validLocation)")
}
}

How it works?

Every time the SDK receive a new location, save it in the device keychain (if needed) and compare to the newest one.
The locally saved data contains also the timestamp of the gps position.

If the travel-time distance calculated using MKDirections (from Mapkit), from the stored position and the newest position is greater that the latest stored timestamp return basically a FALSE.

You shouldn’t be able to reach Lecce from Palermo in 3 minutes.

Location: 45.47 - 9.19 <--- new location
TRAVEL TIME : 0h : 56 mins <--- travel time
LATEST UPDATE: 0h : 46 mins <--- last updated local position
Can reach this location in a valid time?: false

You can read more on github: https://github.com/elpsk/GPSSecurity.

Feel free to fix the code and open pull requests.

Enjoy mocking!